<template>
  <div class="ek-select">
    <el-select
      v-model="value"
      filterable
      @blur="blur"
      @focus="focus"
      @change="change"
      @clear="clear"
      :loading="loading"
      loading-text="加载中"
      no-data-text="无数据"
      :placeholder="placeholder"
      :disabled="disabled"
      :clearable="clearable"
      :multiple="multiple"
      :collapse-tags="collapseTags"
      :collapse-tags-tooltip="collapseTagsTooltip"
      :remote="remote"
      :remote-method="remoteMethod"
      :size="size"
    >
      <el-option
        v-for="item in ekOptions"
        :key="item.value"
        :label="item.label"
        :value="item.value"
      />
    </el-select>
  </div>
</template>

<script setup>
import {
  nextTick,
  defineComponent,
  defineEmits,
  onMounted,
  getCurrentInstance,
  computed,
  ref,
  watch,
  reactive,
} from "vue";
import { getDimensionByCode } from "@/utils/sys.js";

const props = defineProps({
  modelValue: {
    type: [String, Number, Array, Boolean],
    default: "",
  },
  // 显示名称
  name: {
    type: [String, Array],
    default: "",
  },
  // 禁用
  disabled: {
    type: Boolean,
    default: false,
  },
  // 是否显示清除
  clearable: {
    type: Boolean,
    default: true,
  },
  // 默认显示
  placeholder: {
    type: String,
    default: "请选择",
  },
  // 初始化请求接口
  autoInit: {
    type: Boolean,
    default: false,
  },
  // 搜索开启远程
  remote: {
    type: Boolean,
    default: false,
  },
  // 维度编码，存在则直接查询维度接口，优先级比url高
  dimCode: {
    type: String,
    default: "",
  },
  // 远程地址,存在远程地址
  url: {
    type: String,
    default: "",
  },
  //选项，选项里面必须包含label和value
  options: {
    type: Array,
    default: () => [],
  },
  // 是否多选
  multiple: {
    type: Boolean,
    default: false,
  },
  // 多选是否折叠
  collapseTags: {
    type: Boolean,
    default: true,
  },
  collapseTagsTooltip: {
    type: Boolean,
    default: true,
  },
  // 字段映射
  mapping: {
    type: Object,
    default: () => ({
      label: ["label"],
      value: "value",
    }),
  },
  size: {
    type: String,
    default: "default",
  },
});

const {
  appContext: {
    config: { globalProperties },
  },
} = getCurrentInstance();

const { $http } = globalProperties;

const emit = defineEmits([
  "update:modelValue",
  "blur",
  "focus",
  "change",
  "clear",
]);

const value = computed({
  get() {
    if (props.multiple) {
      return props.modelValue;
    } else {
      return props.modelValue;
    }
  },
  set(value) {
    if (props.multiple) {
      emit("update:modelValue", value);
    } else {
      emit("update:modelValue", value);
    }
  },
});
const url = computed(() => {
  if (props.url || props.dimCode) {
    return props.url || props.dimCode;
  } else {
    return "";
  }
});

// 选项列表
const ekOptions = computed(() => {
  if (url.value) {
    return remoteData.value;
  } else {
    return props.options;
  }
});

// 加载中
let loading = ref(false);
// 是否已经加载过
let loaded = ref(false);
function init(isFocus = false) {
  // 存在远程地址，开启初始化获取数据或者存在值
  if (url.value) {
    // 聚焦，开始初始化， 或者存在值且name为空，则直接执行获取数据
    if (
      isFocus ||
      props.autoInit ||
      (!props.multiple && (value.value || value.value === 0) && !props.name) ||
      (props.multiple && value.value?.length && !props.name?.length)
    ) {
      getData(url.value);
    } else {
      if (props.multiple) {
        for (let i = 0; i < value.value.length; i++) {
          remoteData.value.push({
            label: props.name[i],
            value: value.value[i],
          });
        }
      } else {
        remoteData.value.push({
          label: props.name,
          value: value.value,
        });
      }
    }
  }
}
// 获取远程数据
const remoteData = ref([]);
// 获取下拉列表
async function getData(url) {
  // 加载中或者是，已经加载过了直接返回
  if (loaded.value || loading.value) {
    return;
  }
  loading.value = true;
  let list = null;
  if (props.dimCode) {
    list = await getDimensionByCode(props.dimCode);
  } else {
    let res = await $http.post(url);
    if (res.status === "success") {
      list = res.data?.length ? res.data : [];
    }
  }
  if (list?.length) {
    remoteData.value = setMappingData(props.mapping, list);
  }
  loaded.value = true;
  loading.value = false;
}

// 失去焦点
function blur(event) {
  emit("blur", event);
}
// 聚焦
function focus(event) {
  init(true);
  emit("focus", event);
}
// 改变事件, 清空会返回undefined
function change(event) {
  emit("change", event);
}
// 清除事件
function clear() {
  emit("clear");
}

function setMappingData(mapping, data) {
  for (let j in data) {
    let item = data[j];
    item["value"] = item[mapping["value"]];
    let labelArr = [];
    for (let i in mapping["label"]) {
      labelArr.push(item[mapping["label"][i]]);
    }
    item["label"] = labelArr.join("-");
  }
  return data;
}
onMounted(() => {
  init(false);
});
// todo 远程搜索
function remoteMethod() {}

// todo 如果初始化不请求数据如何回显问题
</script>

<style scoped lang="scss"></style>
